package com.jackrain.nea.ad.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.jackrain.nea.ad.api.AdParamSaveCmd;
import com.jackrain.nea.ad.mapper.AdParamMapper;
import com.jackrain.nea.common.ValueHolderUtils;
import com.jackrain.nea.core.db.Tools;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.query.DefaultWebEvent;
import com.jackrain.nea.web.query.QuerySession;
import com.jackrain.nea.web.utils.AdParamUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.util.HashMap;

/**
 * 系统参数
 * @author Yvan
 */
@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "ad")
public class AdParamSaveCmdImpl extends CommandAdapter implements AdParamSaveCmd {

    @Override
    public ValueHolder execute(QuerySession session) throws NDSException {
        DefaultWebEvent event = session.getEvent();
        JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(
                event.getParameterValue("param"), "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue),
                Feature.OrderedField);

        if(param != null){
            JSONObject fixColumn = param.getJSONObject("fixcolumn");
            if(fixColumn != null){
                JSONObject object = fixColumn.getJSONObject("AD_PARAM");
                if(object != null){
                    AdParamMapper mapper = ApplicationContextHandle.getBean(AdParamMapper.class);
                    Long id = param.getLong("objid");
                    object.put("ID", id);
                    if(id > 0){
                        // 修改
                        return update(session, mapper, object);
                    }else{
                        // 新增
                        return add(session, mapper, object);
                    }
                }
            }
        }
        throw new NDSException("当前记录已不存在！");
    }

    /**
     * 修改参数
     * @param session 自定义会话信息
     * @param mapper 映射信息
     * @param object 对象数据
     */
    private ValueHolder update(QuerySession session, AdParamMapper mapper, JSONObject object){
        if(object.containsKey("NAME")){
            checkNameUnique(object.getString("NAME"), object.getLong("ID"), mapper);
        }

        HashMap<String, Object> sqlData = mapper.getById(object.getLong("ID"));
        if(sqlData != null){
            // 判断是否修改内容，true存在修改
            boolean nameFlag = false;
            boolean updateFlag = false;
            if(object.size() > 1){
                if(!object.containsKey("VALUE")){
                    object.put("VALUE", sqlData.get("VALUE"));
                }
                if(!object.containsKey("DEFAULTVALUE")){
                    object.put("DEFAULTVALUE", sqlData.get("DEFAULTVALUE"));
                }
                // 存在名称变更，更新Key
                if(object.containsKey("NAME")){
                    if(!object.getString("NAME").equals(sqlData.get("NAME").toString())){
                        nameFlag = true;
                    }
                }else{
                    object.put("NAME", sqlData.get("NAME"));
                }
                updateFlag = true;
            }

            // 填充数据
            object.put("MODIFIERID", session.getUser().getId());
            object.put("MODIFIEDDATE", new Timestamp(System.currentTimeMillis()));
            object.put("MODIFIERNAME", session.getUser().getName());
            object.put("MODIFIERENAME", session.getUser().getEname());
            int res = mapper.update(object);
            if(res > 0){
                // 同步Redis
                if(nameFlag){
                    // 存在更换名称，重置KEY
                    AdParamUtil.delParam(sqlData.get("NAME").toString());
                    AdParamUtil.setParam(object.getString("NAME"), object.getString("VALUE"), object.getString("DEFAULTVALUE"));
                }else if(updateFlag){
                    // 存在值修改，更新Redis
                    AdParamUtil.setParam(object.getString("NAME"), object.getString("VALUE"), object.getString("DEFAULTVALUE"));
                }
                return ValueHolderUtils.success();
            }
        }
        throw new NDSException("当前记录已不存在！");
    }

    /**
     * 增加参数
     * @param session 自定义会话信息
     * @param mapper 映射信息
     * @param object 对象数据
     */
    private ValueHolder add(QuerySession session, AdParamMapper mapper, JSONObject object){
        checkNameUnique(object.getString("NAME"), object.getLong("ID"), mapper);

        // 填充数据
        Long id = Tools.getSequence("AD_PARAM");
        object.put("ID", id);
        object.put("AD_CLIENT_ID", session.getAdClientId());
        object.put("AD_ORG_ID", session.getUser().getOrgId());
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        object.put("OWNERID", session.getUser().getId());
        object.put("CREATIONDATE", timestamp);
        object.put("OWNERNAME", session.getUser().getName());
        object.put("OWNERENAME", session.getUser().getEname());
        object.put("MODIFIERID", session.getUser().getId());
        object.put("MODIFIEDDATE", timestamp);
        object.put("MODIFIERNAME", session.getUser().getName());
        object.put("MODIFIERENAME", session.getUser().getEname());

        int res = mapper.insert(object);
        if(res > 0){
            // 同步Redis
            AdParamUtil.setParam(object.getString("NAME"), object.getString("VALUE"), object.getString("DEFAULTVALUE"));
            return ValueHolderUtils.success("新增成功！",
                    ValueHolderUtils.createAddErrorData("AD_PARAM", id, null));
        }
        throw new NDSException("当前记录已不存在！");
    }

    /**
     * 检查名称唯一性
     * @param name 名称
     * @param id 主键ID
     * @param mapper 映射对象
     */
    private void checkNameUnique(String name, Long id, AdParamMapper mapper){
        if(name != null){
            Long sqlId = mapper.getIdByName(name);
            if(sqlId != null && !sqlId.equals(id)){
                throw new NDSException("输入的数据已存在：名称");
            }
        }
    }
}
